import { random8BitId, showToast } from "@/utils/tools";
import { defineStore } from "pinia";
import { ref, computed } from 'vue'
import { identityQuestionCategoryName } from '@/static/constants/questionnaire-constant'
import { useQuestionnaireList } from "./questionnaire-list";
import { reqGetQuestionnaire, reqSubmitQuestionnaire, reqGetManagedQuestionnaire, reqGetReceivedQuestionnaire, reqGetQuestionnaireAnswerStatus, reqEditQuestionnaire, reqEditReceivedQuestionnaire } from "@/api/api-questionnaire";
import dayjs from "dayjs";

export const useQuestionnaire = defineStore("questionnaire", () => {
  /** questionnaire-list仓库 */
  const questionnaireListStore = useQuestionnaireList()

  // #region 问卷相关
  /** 当前编辑的问卷 */
  const currentQuestionnaire = ref<Questionnaire>()

  /** 从模板创建问卷 */
  const createQuestionnaireByTemplate = (id: string) => {
    currentQuestionnaire.value = questionnaireListStore.createQuestionnaireByTemplate(id)
  }

  /**
   * 设置当前编辑的问卷
   * @param questionnaire 问卷
   * @description 将当前编辑的问卷设置为传入的问卷
   */
  const setCurrentQuestionnaire = (questionnaire: Questionnaire) => {
    currentQuestionnaire.value = JSON.parse(JSON.stringify(questionnaire))
  }

  /**
   * 获取并设置当前编辑的问卷，用于填写问卷
   * @param id 问卷id
   * @questionnaireType 问卷类型
   */
  const getAndSetCurrentQuestionnaire = async (id: string, questionnaireCategory: QuestionnaireCategory | 'myAnswer' = 'created') => {
    let res: any
    let questionnaireId = ''
    let content = ''
    let isAnswered = true

    // 根据问卷类型通过不同的方法获取问卷
    switch (questionnaireCategory) {
      case 'created':
      case 'deleted':
      case 'expired':
        res = await reqGetManagedQuestionnaire(id)
        questionnaireId = res.data.data.question_id
        content = res.data.data.content
        isAnswered = false

        break;
      // 获取我收到的问卷的情况下
      case 'received':
        res = await reqGetReceivedQuestionnaire(id)
        questionnaireId = res.data.data.answer_id
        content = res.data.data.content_json
        isAnswered = false

        break
    }
    currentQuestionnaire.value = {
      ...JSON.parse(content),
      id: questionnaireId.toString(),
      isAnswered
    }
  }

  /**
   * 编辑当前问卷
   * @param questionnaire 问卷
   */
  const editCurrentQuestionnaire = (questionnaire: AnyObject) => {
    currentQuestionnaire.value = {
      ...currentQuestionnaire.value,
      ...JSON.parse(JSON.stringify(questionnaire)),
    }
  }

  /**
 * 保存当前编辑的问卷，后端会根据question_id判断是更新还是创建
 * @param 操作类型 'edit' 修改创建问卷 'editReceived' 修改已收到的问卷
 */
  const saveCurrentQuestionnaire = (actionType: 'edit' | 'editReceived' = 'edit') => {
    console.log('saveCurrentQuestionnaire', actionType)
    // 如果是编辑问卷
    switch (actionType) {
      case 'edit':
        return reqEditQuestionnaire(currentQuestionnaire.value!)
      // 如果是编辑已收到的问卷

      case 'editReceived':
        return reqEditReceivedQuestionnaire(currentQuestionnaire.value!)
    }
  }

  /**
   * 提交回答的问卷
   */
  const submitCurrentQuestionnaire = () => {
    // 修改反馈时间为当前时间
    currentQuestionnaire.value!.feedbackDate = dayjs().format('YYYY-MM-DD')
    console.log('submitCurrentQuestionnaire', currentQuestionnaire.value)
    reqSubmitQuestionnaire(currentQuestionnaire.value!)
      .then((res: any) => {
        console.log('submitCurrentQuestionnaire res', res)
        currentQuestionnaire.value!.isAnswered = true
        showToast('提交成功')
      })
      .catch((err: any) => {
        console.log('submitCurrentQuestionnaire err', err)
        showToast('提交失败')
      })
  }

  /** 各身份用户回答问卷情况 */
  const questionnaireAnswerStatus = ref<AnswererIdentityAnswerInfo>()

  /** 获取并设置各身份用户回答问卷情况 */
  const getAndSetQuestionnaireAnswerStatus = async (id: string) => {
    const res: any = await reqGetQuestionnaireAnswerStatus(id)
    questionnaireAnswerStatus.value = Object.keys(res.data.data).map((key) => {
      return {
        identity: key,
        isAnswered: res.data.data[key] === '1'
      }
    }) as AnswererIdentityAnswerInfo
    console.log('getAndSetQuestionnaireAnswerStatus', questionnaireAnswerStatus.value)
  }

  // #endregion

  // #region 编辑问题相关
  /** 当前编辑的问题 */
  const currentQuestion = ref<Question>()

  /** 页面焦点问题索引 */
  const focusedQuestionIndex = ref<[number, number]>([0, 0])

  /** 修改当前页面焦点问题索引 */
  const changeFocusedQuestionIndex = (questionListIndex: number, questionIndex: number) => {
    focusedQuestionIndex.value = [questionListIndex, questionIndex]
  }

  /** 当前编辑的问题所属的分类列表 */
  const currentCategoryQuestion = ref<CategoryQuestion>()

  /** 改变当前编辑的问题 */
  const changeCurrentQuestion = (questionIndex: number[]) => {
    const question = currentQuestionnaire.value?.categoryQuestionList?.[questionIndex[0]].questionList[questionIndex[1]]
    currentQuestion.value = question
    currentCategoryQuestion.value = currentQuestionnaire.value?.categoryQuestionList?.[questionIndex[0]]
  }

  /**
   * 编辑当前的问题
   * @param question 问题
   * @description 将当前编辑的问题设置为传入的问题
   */
  const editCurrentQuestion = (question: Question) => {
    currentQuestion.value = JSON.parse(JSON.stringify(question))
  }

  /** 当前编辑问卷中包含的题目类别（不含「身份信息」类别） */
  const currentQuestionCategoryList = computed<Array<string>>(() => {
    return currentQuestionnaire.value?.categoryQuestionList?.map(item => item.questionCategory).filter(item => item !== identityQuestionCategoryName) || []
  })

  //#endregion

  // #region 问题分类相关

  /**
   * 查找是否有这个问题分类
   * @param category 问题分类
   */
  const findQuestionCategory = (category: string): CategoryQuestion | undefined => {
    return currentQuestionnaire.value?.categoryQuestionList?.find(item => item.questionCategory === category)
  }

  /**
   * 添加问题分类
   * @description 如果当前编辑的问卷中没有这个问题分类，则创建，且将传入的问题列表添加到这个分类中
   * @param category 问题分类
   * @param questionList 问题列表
   * @returns 添加成功返回true，添加失败返回false
   */
  const addQuestionCategory = (category: string, questionList?: Array<Question>): boolean => {
    // 查找是否有这个分类
    const categoryQuestionList = currentQuestionnaire.value?.categoryQuestionList?.find(item => item.questionCategory === category)
    // 如果没有则创建
    if (!categoryQuestionList) {
      currentQuestionnaire.value?.categoryQuestionList?.push({
        id: random8BitId(),
        questionCategory: category,
        questionList: questionList || []
      })
      // 添加成功
      return true
    }
    // 如果已经有则返回false
    else {
      // 添加失败
      return false
    }
  }

  /**
   * 编辑当前问题所属分类
   * @param category 问题分类
   * @description 将当前问题从原分类中删除，添加到新分类中，如果新分类不存在，则创建新分类。（不能将问题添加到「您的身份是？」问题的分类中）
   */
  const editCurrentQuestionCategory = (category: string) => {
    // 如果是「您的身份是？」问题，则不做任何操作
    if (category === identityQuestionCategoryName) return

    // 原分类
    const oldCategory = currentCategoryQuestion.value?.questionCategory
    // 如果原分类和新分类相同，则不做任何操作
    if (oldCategory === category) return

    // 从原分类中删除当前问题
    const index = currentCategoryQuestion.value?.questionList.findIndex(item => item.id === currentQuestion.value?.id)
    currentCategoryQuestion.value?.questionList.splice(index!, 1)
    // 查找是否有这个分类
    const categoryQuestion = currentQuestionnaire.value?.categoryQuestionList?.find(item => item.questionCategory === category)
    // 如果有这个分类，则将当前问题添加到这个分类中
    if (categoryQuestion) {
      categoryQuestion.questionList.push(currentQuestion.value!)
    } else {
      // 如果没有这个分类，则创建这个分类，并将当前问题添加到这个分类中
      addQuestionCategory(category, [currentQuestion.value!])
    }
  }

  /**
   * 修改各分类问题列表的次序
   * @param 各分类的次序
   */
  const sortQuestionListsByCategory = (categoryOrder: Array<string>) => {
    currentQuestionnaire.value?.categoryQuestionList?.sort((a, b) => {
      const aIndex = categoryOrder.findIndex(item => a.questionCategory === item)
      const bIndex = categoryOrder.findIndex(item => b.questionCategory === item)
      return aIndex - bIndex
    })
  }

  //#endregion

  //#region 添加、删除、移动问题相关
  /**
   * 添加问题
   * @description 将传入的问题添加到当前编辑的问卷中，如果当前编辑的问卷中没有这个问题分类，则创建这个分类
   * @param question 问题
   * @param category 问题分类
   * @param position 问题位置，默认为最后
   */
  const addQuestion = (question: Question, category: string, position: number = -1) => {
    // 如果没有这个分类，则创建这个分类
    if (!findQuestionCategory(category)) {
      addQuestionCategory(category, [question])
    }

    // 找到这个分类，并将问题添加到这个分类的对应位置
    const categoryQuestionList = currentQuestionnaire.value?.categoryQuestionList?.find(item => item.questionCategory === category)
    // 如果传入的position为-1，则将问题添加到该分类的最后一个问题
    categoryQuestionList?.questionList.splice(position === -1 ? categoryQuestionList.questionList.length : position, 0, question)
    console.log('questionList', categoryQuestionList?.questionList)

    // 将焦点问题索引修改为该问题对应的索引
    const questionListIndex = currentQuestionnaire.value?.categoryQuestionList?.findIndex(item => item.questionCategory === category) ?? 1
    // 如果传入的position为-1，则将问题索引设置为该分类的最后一个问题
    const questionIndex = position === -1 ? (categoryQuestionList?.questionList.length || 1) - 1 : position

    // 将焦点问题索引修改为该问题对应的索引
    changeFocusedQuestionIndex(questionListIndex, questionIndex)
  }

  /**
   * 删除题目
   * @param questionIndex 问题索引
   */
  const deleteQuestion = (questionIndex: number[]) => {
    const questionList = currentQuestionnaire.value?.categoryQuestionList?.[questionIndex[0]]
    questionList?.questionList.splice(questionIndex[1], 1)
  }

  /**
   * 移动题目
   * @description 将当前编辑的问卷中的问题上移或下移
   * @param questionIndex 问题索引
   * @param direction 移动方向
   * @param distance 移动距离，默认为1
   */
  const moveQuestion = (questionIndex: number[], direction: 'up' | 'down', distance: number = 1) => {
    const questionList = currentQuestionnaire.value?.categoryQuestionList?.[questionIndex[0]]
    const question = questionList?.questionList.splice(questionIndex[1], 1)[0]
    switch (direction) {
      case 'up':
        questionList?.questionList.splice(questionIndex[1] - distance, 0, question!)
        break
      case 'down':
        questionList?.questionList.splice(questionIndex[1] + distance, 0, question!)
        break
    }
  }
  // #endregion

  // #region 填写问卷相关
  /**
   * 更新答案
   * @param questionIndex 问题索引
   * @param answer 答案
   */
  const updateAnswer = (questionIndex: number[], answer: string) => {
    console.log('questionIndex', questionIndex)
    console.log('answer', answer)
    const question = currentQuestionnaire.value?.categoryQuestionList?.[questionIndex[0]]?.questionList[questionIndex[1]]
    if (!question) return
    question.answer = answer
  }

  /**
   * 将当前回答的问卷保存到本地
   * @description 将当前回答的问卷保存到本地，如果本地已经有这个问卷，则覆盖
   * @type 保存类型，answer 回答的问卷
  */
  const saveCurrentQuestionnaireToLocal = (type: 'answer' = 'answer') => {
    // 如果当前问卷没有id，则不保存
    if (currentQuestionnaire.value?.id === '') return
    console.log('currentQuestionnaire.value', currentQuestionnaire.value)
    const key = `${type}-${currentQuestionnaire.value?.id}`
    uni.setStorageSync(key, currentQuestionnaire.value)
  }

  /**
   * 获取并设置当前要回答的问卷
   * @param id 问卷id
   */
  const getAndSetCurrentQuestionnaireAnswer = async (id: string) => {
    // 先从后端获取，判断是否提交过
    let res: any
    /** 是否已经回答过了 */
    let isAnswered = false
    try {
      res = await reqGetQuestionnaire(id)
      isAnswered = res.data.data.isFirst === '0'
    } catch (e) {
      uni.showToast({ title: '获取问卷失败', })
      console.error(e)
    }

    // 如果已经回答过了，则将获取到的问卷设置为当前问卷
    if (isAnswered) {
      const questionnaire: Questionnaire = {
        ...JSON.parse(res.data.data.answer.content_json),
        id: res.data.data.answer.target_id,
        answerId: res.data.data.answer.answer_id,
        isAnswered
      }
      setCurrentQuestionnaire(questionnaire)
    }
    // 如果没有回答过，则尝试从本地获取问卷
    else {
      const key = `answer-${id}`
      // 如果本地有这个问卷，则从本地获取
      const localQuestionnaire = uni.getStorageSync(key)
      if (localQuestionnaire) {
        setCurrentQuestionnaire(localQuestionnaire)
        return
      }
      // 如果本地没有这个问卷，则将后端获取的问卷设置为当前问卷
      const questionnaire = {
        ...JSON.parse(res.data.data.content),
        id: res.data.data.question_id.toString(),
        isAnswered
      }
      setCurrentQuestionnaire(questionnaire)
    }
    console.log('getAndSetCurrentQuestionnaireAnswer', currentQuestionnaire.value)
  }

  //#endregion
  return {
    createQuestionnaireByTemplate,
    currentQuestionnaire,
    setCurrentQuestionnaire,
    getAndSetCurrentQuestionnaire,
    editCurrentQuestionnaire,
    saveCurrentQuestionnaire,
    submitCurrentQuestionnaire,

    questionnaireAnswerStatus,
    getAndSetQuestionnaireAnswerStatus,

    currentQuestion,
    focusedQuestionIndex,
    changeFocusedQuestionIndex,

    currentCategoryQuestion,
    currentQuestionCategoryList,
    addQuestionCategory,
    editCurrentQuestionCategory,
    sortQuestionListsByCategory,
    editCurrentQuestion,
    changeCurrentQuestion,
    addQuestion,
    deleteQuestion,
    moveQuestion,

    updateAnswer,
    saveCurrentQuestionnaireToLocal,
    getAndSetCurrentQuestionnaireAnswer
  }
})

